package com.xykj.enterprise.wechat.util.http;

import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Feng Chen
 */
public class HttpUtil2 {

    // 设置连接超时时间，单位毫秒。
    private static final int CONNECT_TIMEOUT = 3000;

    // 请求获取数据的超时时间(即响应时间)，单位毫秒。
    private static final int SOCKET_TIMEOUT = 3000;

    public static String get(String url) throws Exception {
        return get(url, null, null);
    }

    public static String get(String url, Map<String, Object> params) throws Exception {
        return get(url, null, params);
    }

    /**
     * Get 请求
     *
     * @param url
     * @param headers
     * @param params
     * @return
     * @throws Exception
     */
    public static String get(String url, Map<String, String> headers, Map<String, Object> params) throws Exception {
        // 创建 HttpClient 对象
        CloseableHttpClient httpClient = null;

        try {
            httpClient = HttpClients.createDefault();

            // 创建访问地址
            URIBuilder uriBuilder = new URIBuilder(url);
            if (params != null && !params.isEmpty()) {
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    if (entry.getValue() == null) {
                        uriBuilder.setParameter(entry.getKey(), "");
                    } else {
                        uriBuilder.setParameter(entry.getKey(), String.valueOf(entry.getValue()));
                    }
                }
            }

            // 创建 http 对象
            HttpGet httpGet = new HttpGet(uriBuilder.build());

            // 请求参数
            httpGet.setConfig(RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT)
                    .setSocketTimeout(SOCKET_TIMEOUT)
                    .build()
            );

            // 设置请求头
            packageHeader(headers, httpGet);

            //创建 HttpResponse 对象
            return execute(httpClient, httpGet);
        } finally {
            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    // ignore ...
                }
            }
        }

    }

    public static String post(String url, Map<String, String> headers, Map<String, Object> params) throws Exception {
        // 创建 HttpClient 对象
        CloseableHttpClient httpClient = null;

        try {
            httpClient = HttpClients.createDefault();

            // 创建 Http 对象
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT)
                    .setSocketTimeout(SOCKET_TIMEOUT)
                    .build()
            );

            // 设置请求头
            packageHeader(headers, httpPost);

            // 设置请求参数
            packageParam(params, httpPost);

            return execute(httpClient, httpPost);
        } finally {
            if (httpClient != null) {
                httpClient.close();
            }
        }

    }

    /**
     * 添加请求头
     *
     * @param headers
     * @param httpMethod
     */
    private static void packageHeader(Map<String, String> headers, HttpRequestBase httpMethod) {
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpMethod.setHeader(entry.getKey(), entry.getValue());
            }
        }
    }

    private static void packageParam(Map<String, Object> params, HttpEntityEnclosingRequestBase httpMethod) throws UnsupportedEncodingException {
        if (params != null && !params.isEmpty()) {
            List<NameValuePair> pairs = new ArrayList<>();
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                pairs.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
            }
            httpMethod.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
        }
    }

    /**
     * 执行请求
     *
     * @param httpClient
     * @param httpMethod
     * @return
     * @throws Exception
     */
    private static String execute(CloseableHttpClient httpClient, HttpRequestBase httpMethod) throws Exception {
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求
            httpResponse = httpClient.execute(httpMethod);

            // 获取返回结果
            if (httpResponse != null && httpResponse.getStatusLine() != null) {
                return EntityUtils.toString(httpResponse.getEntity());
            }
            return null;
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    // ignore...
                }
            }
        }
    }

    public static String post(String url, String data) throws Exception {
        CloseableHttpClient httpclient = null;
        try {
            httpclient = HttpClients.createDefault();
            HttpPost httppost = new HttpPost(url);
            StringEntity stringentity = new StringEntity(data,
                    ContentType.create("text/json", "UTF-8"));
            httppost.setHeader("Content-Type", "application/json");
            httppost.setEntity(stringentity);
            return execute(httpclient, httppost);

        } finally {
            if (httpclient != null) {
                httpclient.close();
            }

        }
    }

}
